﻿#pragma once

//#define		DEMO		//演示数据
#define		QC_CNNMACHINE	//连接色谱仪
#define		SOCKET_MSG
//#define		NET_COMMAND		//采用命令流的方式，而不是立刻执行

#define		METHOD_FILE_VERSION 101
#define		MAX_CALPOINTS		10
#define		MAX_CHROMSAMPLES	3800
#define		DATAFREQUENCE		40

// 配色方案
#define USE_DEEP_BLUE 1
// #define USE_PURPLE_PINK 1
// #define USE_GREEN_CYAN 1
 //#define USE_BLACK_BLUE 1
 //#define USE_TIFFANY_BLUE 1

// 背景色渐变定义
#if defined(USE_DEEP_BLUE)
    #define BACKCOLOR1 RGB(0x00, 0x33, 0x66) // 深蓝色 (#003366)
    #define BACKCOLOR2 RGB(0x66, 0xCC, 0xFF) // 浅蓝色 (#66CCFF)
    //#define BACKCOLOR1 RGB(0x00, 0x99, 0xEE) // 深蓝色 (#003366)
    //#define BACKCOLOR2 RGB(0x66, 0xCC, 0xFF) // 浅蓝色 (#66CCFF)
    #define TXTFORCOLOR RGB(255, 255, 255)   // 白色
    //#define TXTBKCOLOR RGB(0x00, 0x33, 0x66)        // 深蓝色
#elif defined(USE_PURPLE_PINK)
    #define BACKCOLOR1 RGB(0x4B, 0x00, 0x82)  // 深紫色 (#4B0082)
    #define BACKCOLOR2 RGB(0xFF, 0x69, 0xB4)   // 粉红色 (#FF69B4)
    #define BACKCOLOR1 RGB(0x8A, 0x2B, 0xE2)     // 紫罗兰色 (#8A2BE2)
    #define TXTFORCOLOR RGB(255, 255, 255)     // 白色
    #define TXTBKCOLOR RGB(0x4B0082)            // 深紫色
#elif defined(USE_GREEN_CYAN)
    #define BACKCOLOR1 RGB(0x00, 0x4D, 0x00)   // 深绿色 (#004d00)
    #define BACKCOLOR2 RGB(0x00, 0xCC, 0xCC)    // 青色 (#00cccc)
    #define BACKCOLOR1 RGB(0x00, 0x7A, 0x7A)      // 中绿色 (#007A7A)
    #define TXTFORCOLOR RGB(255, 255, 255)      // 白色
    #define TXTBKCOLOR RGB(0x004D00)             // 深绿色
#elif defined(USE_BLACK_BLUE)
    #define BACKCOLOR1 RGB(0x00, 0x00, 0x00)    // 黑色 (#000000)
    #define BACKCOLOR2 RGB(0x00, 0xBF, 0xFF)     // 亮蓝色 (#00BFFF)
    #define BACKCOLOR1 RGB(0x00, 0x00, 0x8B)       // 深蓝色 (#00008B)
    #define TXTFORCOLOR RGB(255, 255, 255)       // 白色
    #define TXTBKCOLOR RGB(0x000000)              // 黑色
#elif defined(USE_TIFFANY_BLUE)
    #define BACKCOLOR1 RGB(0x0A, 0xBA, 0xB5)     // 深蒂芙尼蓝 (#0ABAB5)
    #define BACKCOLOR2 RGB(0xA1, 0xDB, 0xD4)      // 浅蒂芙尼蓝 (#A1DBD4)
    #define BACKCOLOR1 RGB(0x4D, 0xB6, 0xB9)        // 中蒂芙尼蓝 (#4DB6B9)
    #define TXTFORCOLOR RGB(255, 255, 255)        // 白色
    #define TXTBKCOLOR RGB(0x0ABAB5)              // 深蒂芙尼蓝
#else
    #error "No color scheme defined. Please define one of the color schemes."
#endif


//字体大小
#define	LARGEFONTSIZE 130
#define SMALLFONTSIZE 100

extern CString m_strAppPath;
extern 	_ConnectionPtr	m_pCnnWell;
extern CRITICAL_SECTION m_cSend;			//网络访问

extern void WriteLog(CString  strBuf);
//extern void WriteSysLog(CString  strBuf);

CString ReadINI(CString RootName, CString KeyName);
void    SaveINI(CString RootName, CString KeyName, CString Value);
void    SaveINIFile(CString RootName, CString KeyName, int Value);
void    SaveINIFile(CString RootName, CString KeyName, double Value);
//字符处理
extern CStringArray* DivString(CString strSource, CString strSperate, int* nLenght);
extern int strfind(char* srcstr, char* deststr);
extern int strfindEx(char* srcstr, char* deststr, int nLength);
char * right(char* dst, char* src, int n);
void	stradd( char* sBase, int nOrgLen,  char* sAdd, int nAddLen);
extern char* wchar2char(CString str);
extern char* CStrToChar(CString strSrc);
extern CString char2wchar(char* str);
extern CTime CStringToCTime(CString strBuf);
extern long StrHex2Dec(CString strHex);
extern int StrToHex(CString str, BYTE *btData);

BOOL FileExist(CString filename);
float  FileSize(CString filename);
extern void BxGradientFill(CDC* pDC, CRect rt, COLORREF clrFillBackColor1, COLORREF clrFillBackColor2, int nFillStyle);
extern void DrawInBorder(CDC* pDC, CRect rt, COLORREF tc = RGB(128, 128, 128), COLORREF bc = RGB(255, 255, 255));
int			GetChTypeFromFileName(CString strFileName);

//////////////////////////////////////////////////////////////////
//TTS 语音输出
extern bool  bSpeechNow;
extern "C" _declspec(dllexport)  int Speech(CString strTextString);
extern UINT	Speech_Info1(LPVOID pParam);
extern UINT	Speech_Info2(LPVOID pParam);

/////////////////////////////////////////////////////////////////
//实现延迟更新机制
template <typename T>
class DelayedUpdate
{
public:
    // 构造函数，初始值和可选的延时时间，默认延时为500毫秒
    DelayedUpdate(T initialValue = T())
        : value(initialValue) {}

    // 重载赋值运算符
    T& operator=(const T& newValue)
    {
        if (newValue != value)
        {
			num++;
            if (num >= 60)
            {
                value = newValue;
                num = 0;
            }
		}else{
			num = 0;
		}
        return value;
    }

    // 重载 + 操作符
    template <typename U>
    auto operator+(const U& otherValue) const -> decltype(value + otherValue)
    {
        return value + otherValue;
    }

    // 重载 - 操作符
    template <typename U>
    auto operator-(const U& otherValue) const -> decltype(value - otherValue)
    {
        return value - otherValue;
    }

    // 重载 * 操作符
    template <typename U>
    auto operator*(const U& otherValue) const -> decltype(value * otherValue)
    {
        return value * otherValue;
    }

    // 重载 / 操作符
    template <typename U>
    auto operator/(const U& otherValue) const -> decltype(value / otherValue)
    {
        return value / otherValue;
    }

    // 重载 == 操作符，用于比较当前值
    bool operator==(const T& otherValue) const
    {
        return value == otherValue;
    }

    // 重载 != 操作符
    bool operator!=(const T& otherValue) const
    {
        return value != otherValue;
    }

    // 重载转换操作符，允许隐式转换为 T 类型
    operator T() const
    {
        return value;
    }

private:
    T value;
    DWORD num;
};

// 非成员函数，提供右操作数为 DelayedUpdate 的加法操作
template <typename T, typename U>
auto operator+(const T& lhs, const DelayedUpdate<U>& rhs) -> decltype(lhs + static_cast<T>(rhs))
{
    return lhs + static_cast<T>(rhs);
}

// 非成员函数，提供右操作数为 DelayedUpdate 的减法操作
template <typename T, typename U>
auto operator-(const T& lhs, const DelayedUpdate<U>& rhs) -> decltype(lhs - static_cast<T>(rhs))
{
    return lhs - static_cast<T>(rhs);
}

// 非成员函数，提供右操作数为 DelayedUpdate 的乘法操作
template <typename T, typename U>
auto operator*(const T& lhs, const DelayedUpdate<U>& rhs) -> decltype(lhs * static_cast<T>(rhs))
{
    return lhs * static_cast<T>(rhs);
}

// 非成员函数，提供右操作数为 DelayedUpdate 的除法操作
template <typename T, typename U>
auto operator/(const T& lhs, const DelayedUpdate<U>& rhs) -> decltype(lhs / static_cast<T>(rhs))
{
    return lhs / static_cast<T>(rhs);
}
////////////////////////////////////////////////////////////////
//延时控制
class CMyThreadSafeTimeout
{
public:
	CMyThreadSafeTimeout();
	bool IsTimeout();
	void SetTime(DWORD delay);
private:
	DWORD m_timeout;          // Timeout period in milliseconds
	DWORD m_startTickCount;   // Starting tick count
	CCriticalSection m_criticalSection; // Critical section for thread safety
};

////////////////////////////////////////////////////////////////
//DPI缩放
extern float g_DPIScaleX;
extern float g_DPIScaleY;
//十点标定
struct FlowCali
{
	double  dP[10];		//信号
	double  dF[10];		//值
	double	dValue;		//最终计算值
};

//单组份标定信息
struct Single_Component
{
	CString    strName;				//名称
	double   RealyTime;				//出峰时间
	double	Wrap;					//峰宽
	double	PPM[MAX_CALPOINTS];		//标样浓度--系统默认单位%;
	double	Area[MAX_CALPOINTS];	//标准曲线的面积或者高度（用于最后的积分计算）
	double	OrgArea[MAX_CALPOINTS];		//标准曲线的面积
	double	OrgHeight[MAX_CALPOINTS];	//标准曲线的峰高度
	short	nStandardGas[MAX_CALPOINTS];			//0--不是标准混合样，1--是0.1%浓度混合样,1--是1%浓度混合样，2--是10%浓度混合样

	void operator=(Single_Component& sc)
	{
		strName=sc.strName;
		RealyTime=sc.RealyTime;
		Wrap=sc.Wrap;
		for (int k = 0; k < MAX_CALPOINTS; k++)
		{
			PPM[k]= sc.PPM[k];					//标样浓度
			Area[k]= sc.Area[k];				//标准曲线的面积或者高度
			OrgArea[k]= sc.OrgArea[k];
			OrgHeight[k]= sc.OrgHeight[k];
			nStandardGas[k]= sc.nStandardGas[k];
		}
	}
};
//标定信息
struct Calibrate_Info
{
	CString		strFolder;			//色谱图谱保存文件夹
	Single_Component   scA[10];		//出峰时间,分别为0-C1,1--C2,2--C3,3--IC4,4--NC4,5--IC5,6--NC5,7--TG,8--CO2,9--He
	Single_Component   scB[10];		//出峰时间,分别为0-C1,1--C2,2--C3,3--IC4,4--NC4,5--IC5,6--NC5,7--TG,8--CO2,9--He
	double	dPar[7];				//理论全烃的计算系数

	void Serialize(CArchive& ar)
	{
		if (ar.IsLoading())
		{
			ar >> strFolder;
			for (int i = 0; i < 10; i++)
			{
				ar >> scA[i].strName;					//色谱名
				ar >> scA[i].RealyTime;					//出峰时间
				ar >> scA[i].Wrap;						//峰宽
				for (int k = 0; k < MAX_CALPOINTS; k++)
				{
					ar >> scA[i].PPM[k];				//标样浓度
					ar >> scA[i].Area[k];				//标准曲线的面积或者高度
					ar >> scA[i].OrgArea[k];
					ar >> scA[i].OrgHeight[k];
					ar >> scA[i].nStandardGas[k];
				}
			}
			for (int i = 0; i < 10; i++)
			{
				ar >> scB[i].strName;					//色谱名
				ar >> scB[i].RealyTime;					//出峰时间
				ar >> scB[i].Wrap;						//峰宽
				for (int k = 0; k < MAX_CALPOINTS; k++)
				{
					ar >> scB[i].PPM[k];				//标样浓度
					ar >> scB[i].Area[k];				//标准曲线的面积或者高度
					ar >> scB[i].OrgArea[k];
					ar >> scB[i].OrgHeight[k];
					ar >> scB[i].nStandardGas[k];
				}
			}
			for (int i = 0; i < 7; i++)
				ar >> dPar[i];
		}
		else
		{
			ar << strFolder;
			for (int i = 0; i < 10; i++)
			{
				ar << scA[i].strName;					//色谱名
				ar << scA[i].RealyTime;				//出峰时间
				ar << scA[i].Wrap;						//峰宽
				for (int k = 0; k < MAX_CALPOINTS; k++)
				{
					ar << scA[i].PPM[k];				//标样浓度
					ar << scA[i].Area[k];			//标准曲线的面积或者高度
					ar << scA[i].OrgArea[k];
					ar << scA[i].OrgHeight[k];
					ar << scA[i].nStandardGas[k];
				}
			}
			for (int i = 0; i < 10; i++)
			{
				ar << scB[i].strName;					//色谱名
				ar << scB[i].RealyTime;				//出峰时间
				ar << scB[i].Wrap;						//峰宽
				for (int k = 0; k < MAX_CALPOINTS; k++)
				{
					ar << scB[i].PPM[k];				//标样浓度
					ar << scB[i].Area[k];			//标准曲线的面积或者高度
					ar << scB[i].OrgArea[k];
					ar << scB[i].OrgHeight[k];
					ar << scB[i].nStandardGas[k];
				}
			}
			for (int i = 0; i < 7; i++)
				ar << dPar[i];
		}
	}
};

//双通道校准--以A通道为基准信号
struct TWOCH_SIG_CALI				
{
	//信号校准
	float	dOrgSignal[2][2];	//原始信号：100%甲烷 [种类][通道]  0-高度，1-面积
	float	dSignalBaseA;		//基线A
	float	dSignalBaseB;		//基线B
	double	dKc;				//系数--不使用，但保留着
	/*
	float	dKa;				//通道A的斜率
	float	dKb;				//通道B的斜率
	通道B的信号校准到通道A上，使用如下的公式
	Sa =(Sb-Bb)* Kc + Ba = Ka / Kb * (Sb-Bb) + Ba
	Kc= Ka / Kb
	*/
	//组份峰面积校正107
	float	dALLHAOrg[7][2];	//0.1%低混合样A时的峰高和面积原始值
	float	dBLLHAOrg[7][2];	//0.1%低混合样B时的峰高和面积原始值
	float	dALHAOrg[7][2];		//1%低混合样A时的峰高和面积原始值
	float	dBLHAOrg[7][2];		//1%低混合样B时的峰高和面积原始值
	float	dAHHAOrg[7][2];		//10%高混合样A时的峰高和面积原始值
	float	dBHHAOrg[7][2];		//10%高混合样B时的峰高和面积原始值
	double	dHAdjPar[7][2];		//峰高法：较正系数 y= -0.021ln(x) + 1.1611  x为B峰高，y为A/B的比值
	double	dAAdjPar[7][2];		//面积法：较正系数 y = -3E-05x + 1.0588	x为B面积，y为A/B的比值
								//2022-3-3 也改为对数校正法 y = -0.014ln(x) + 1.1066R² = 0.9713   x为B面积，y为A/B的比值
	float	dSpare[200];			//备用，后期算法改进

	TWOCH_SIG_CALI()
	{
		dSignalBaseA = dSignalBaseB = 0;
		dKc = 1;
		for (int i = 0; i < 7; i++)
		{
			dHAdjPar[i][0] = dHAdjPar[i][1] = 1;
			dAAdjPar[i][0] = dAAdjPar[i][1] = 1;
			//dAAdjPar[i][0] = 0;
			//dAAdjPar[i][1] = 1;
		}
	}

	void	Calculate();
};

//仪器参数设置--显示参数设置
struct Machine
{
	double	dSamplePressure;	//样品气压力
	double	dInjectTime;		//预切柱时间  （秒，可带小数）
	double	dStabilizeTime;		//稳定时间    （秒，可带小数）
	double	dColumTemp;			//设定柱温
	double	dFid1Temp;			//设定FID1温 
	double	dFid2Temp;			//设定FID2温 
	double	dFid3Temp;			//设定FID3温
	double	dAFlameout;			//A FID温度（熄火信号）
	double	dBFlameout;			//B FID温度（熄火信号）
	double	dCFlameout;			//C FID温度（熄火信号）
	double  dSignalSensitivity[3]; //信号灵敏度

	double	dAAirPSet;			//组份空气压力设定 组份A通道
	double	dAH21PSet;			//预切柱压力设定
	double	dAH22PSet;			//主柱压力设定
	double	dBAirPSet;			//组份空气压力设定 组份B通道
	double	dBH21PSet;			//预切柱压力设定
	double	dBH22PSet;			//主柱压力设定
	double	dCAirPSet;			//全烃空气压力设定 全烃通道
	double	dCH2PSet;			//全烃氢气压力设定
	double	dCSamplePSet;		//全烃样品气压力设定

	FlowCali			sFlow[9];	//流量的标定   //0--组份A空气,1--组份A预切,2--组份A主柱
									//3--组份B空气,4--组份B预切,5--组份B主柱
									//6--全烃空气,7--全烃氢气,8--样品气
	float	nYMax[3];				//坐标轴的设置  0--组份A，1--组份B，2--TG C
	float	nYMin[3];
	int		nYAuto;					//坐标轴自适用，0--自适用，1--自定义
	int		nXScale;				//分析周期
	COLORREF nLineColor[3];			//谱图线的颜色 
	int		 nLineWidth[3];
	//组份线的颜色
	COLORREF nComColor[9];			//总烃+7个组份+CO2
	int		 nComShow[9];			//0--不显示，1--显示
	int		 nIntMethod;			//积分方法 0--面积法，1--峰高法

	TWOCH_SIG_CALI  tsc;			//两通道校准
	void Serialize(CArchive& ar);
};

//谱图文件
struct Chrom_File
{
	float dLagDepth;							//迟到井深
	int		nActurePoints;						//实际数据量
	double   CA[MAX_CHROMSAMPLES];				//通道A数据,单位mV
	double   CB[MAX_CHROMSAMPLES];				//通道B数据--全烃
	int		CASIndex[MAX_CHROMSAMPLES];			//信号盒中的序号--临时，不用于文件存储
	int		CBSIndex[MAX_CHROMSAMPLES];

	int   CAIndex;								//A通道当前数据
	int   CBIndex;								//B通道当前数据
	double	dPeakH[7];							//7--全组份峰高
	double	dPeakA[7];							//7--全组份面积
	double	dPeakS[7];							//7--全组份时间
	double	dResult[7];							//7--全组份值
	double	dTGResult;
	double	dTGMaxSignal;						//这一周期中全烃的最大信号值
	double	dCO2Result;
	long	lTime;								//谱图时间

	Chrom_File()
	{
		dLagDepth = 0;
		for (int i = 0; i < MAX_CHROMSAMPLES; i++)
		{
			CA[i] = -999;
			CB[i] = -999;
			CASIndex[i] = CBSIndex[i] = 0;
		}
		CAIndex = CBIndex = 0;
		for (int i = 0; i < 7; i++)
		{
			dPeakH[i] = dPeakA[i] = dPeakS[i] = dResult[i] = 0;
		}
		dTGResult = dTGMaxSignal = dCO2Result =  0;
		lTime = CTime::GetCurrentTime().GetTime();
	}

	//初始化，清空原先数据
	void Init()
	{
		dLagDepth = 0;
		for (int i = 0; i < MAX_CHROMSAMPLES; i++)
		{
			CA[i] = -999;
			CB[i] = -999;
			CASIndex[i] = CBSIndex[i] = 0;
		}
		CAIndex = CBIndex = 0;
		for (int i = 0; i < 7; i++)
		{
			dPeakH[i] = dPeakA[i] = dPeakS[i] = dResult[i] = 0;
		}
		dTGResult = dTGMaxSignal = dCO2Result  = 0;
		lTime = CTime::GetCurrentTime().GetTime();
	}

	void operator=(Chrom_File& cf)
	{
		dLagDepth = cf.dLagDepth;
		nActurePoints = cf.nActurePoints;
		for (int i = 0; i < MAX_CHROMSAMPLES; i++)
		{
			CA[i] = cf.CA[i];
			CB[i] = cf.CB[i];
			CASIndex[i] = cf.CASIndex[i];
			CBSIndex[i] = cf.CBSIndex[i];
		}
		CAIndex = cf.CAIndex;
		CBIndex = cf.CBIndex;
		for (int i = 0; i < 7; i++)
		{
			dPeakH[i] = cf.dPeakH[i];
			dPeakA[i] = cf.dPeakA[i];
			dPeakS[i] = cf.dPeakS[i];
			dResult[i] = cf.dResult[i];
		}
		dTGResult = cf.dTGResult;
		dTGMaxSignal = cf.dTGMaxSignal;
		dCO2Result = cf.dCO2Result;
		lTime = cf.lTime;
	}

	void Serialize(CArchive& ar)
	{
		if (ar.IsLoading())
		{
			ar >> dLagDepth;
			ar >> nActurePoints;
			for (int i = 0; i < nActurePoints; i++)
			{
				ar >> CA[i];
				ar >> CB[i];
				ar >> CASIndex[i];
				ar >> CBSIndex[i];
			}
			ar >> CAIndex;
			ar >> CBIndex;
			for (int i = 0; i < 7; i++)
			{
				ar >> dPeakH[i];
				ar >> dPeakA[i];
				ar >> dPeakS[i];
				ar >> dResult[i];
			}
			ar >> dTGResult;
			ar >> dTGMaxSignal;
			ar >> dCO2Result;
			ar >> lTime;
		}
		else
		{
			ar << dLagDepth;
			ar << nActurePoints;
			float dMaxTG = -99;
			for (int i = 0; i < nActurePoints; i++)
			{
				ar << CA[i];
				ar << CB[i];
				ar << CASIndex[i];
				ar << CBSIndex[i];
				if (dMaxTG < CB[i]) dMaxTG = CB[i];
			}
			dTGMaxSignal = dMaxTG;
			ar << CAIndex;
			ar << CBIndex;
			for (int i = 0; i < 7; i++)
			{
				ar << dPeakH[i];
				ar << dPeakA[i];
				ar << dPeakS[i];
				ar << dResult[i];
			}
			ar << dTGResult;
			ar << dTGMaxSignal;
			ar << dCO2Result;
			ar << lTime;
		}
	}

	//转换成文本文件
	void ToTxt(CString strFileName);
};


struct MachineStatus			//实测仪器状态
{
	int		nStatus;			//0--软件启动，1--仪器升温，2--仪器点火，3--仪器稳定，4--仪器就绪,5--正常分析，
								//6--点火失败,7--故障1，异外熄火，氢气关闭，8--故障2，超温保护，氢气关闭。
	int		nAnaStatus;			//0-就绪状态，1--启动分析，2--分析状态，
	double	dSamplePressure;	//样品气压力
	double	dColumTemp;			//柱温
	double	dFid1Temp;			//FID1温度
	double	dFid2Temp;			//FID2温度
	double	dFid3Temp;			//FID3温度
	double   dFidAV;			//A FID 信号
	double   dFidBV;			//B FID 信号
	double   dFidCV;			//C FID 信号
	double   dCO2V;				//CO2 信号
	double	dH2SV;				//H2S电压；mv
	double	dAirP;				//大气压力

	double	dFlow[9];			//6个流量传感器
	double	m_dAAirP;			//A组份空气压力
	double	m_dAH21P;			//A预切柱压力
	double	m_dAH22P;			//A主柱压力
	double	m_dBAirP;			//B组份空气压力
	double	m_dBH21P;			//B预切柱压力
	double	m_dBH22P;			//B主柱压力
	double	m_dTGAirP;			//全烃空气压力
	double	m_dTGH2P;			//全烃氢气压力
	double	m_dTGSampleP;		//全烃样品气压力--未使用，2022启用

	DelayedUpdate<int> 		m_nFid1Status;				//FID1 点火状态--组份A  0=失败；1=成功
	DelayedUpdate<int> 		m_nFid2Status;				//FID2 点火状态--组份B
	DelayedUpdate<int> 		m_nFid3Status;				//FID3 点火状态--全烃
	DelayedUpdate<int> 		m_nEPCStatus;				//EPC 通信状态  WNT 2024-01-13 变成3态 0--正常，1--关闭， 2--压力有误差

	long	m_nMachineSN;				//硬件序列号 21001
	long	m_nProduceDate;				//出厂日期 211108
	long	m_nFirmwareVer;				//固件版本400201 (40表示双通道,20表示普通,2.1版本）
};
//录井WITS
struct ChromWITS
{
	CString strOutIP;				//DML-LS 计算机地址
	int		nOutPort;				//端口号
	int		nOutMode;				//模式，0--Server,1--Client
	int		nOutAutoOpen;			//启动时就打开 0-不打开，1--打开
	CString strOutWits[16];			//
	double   dOutValue[16];
	int		nWitsOutStatus;			//WITS OUT 状态 0-关闭，1--打开
	CString strWitsOutBuf;

	CString strInIP;				//DML-LS 计算机地址
	int		nInPort;				//端口号
	int		nInMode;				//模式，0--Server,1--Client
	int		nInAutoOpen;			//启动时就打开 0-不打开，1--打开
	CString strInWits[5];			//迟到井深,1#pump,2#pump,3#pump，迟到时间
	double   dInValue[5];
	int		nWitsInStatus;			//WITS IN 状态 0-关闭，1--打开
	CString strWitsInBuf;
};

//自动根据斜率积分
struct CurveData				//谱图数据点
{
	CurveData()
	{
		dTime = dVar = 0;
	}
	double dTime;
	double dVar;
};

struct PEAK_INOF				//峰信息
{
	CString strPeakName;		//峰名
	double	dPeakTimeB;			//起始时间
	double	dPeakTimeE;			//结束时间
	double	dBaseLineB;			//起始基线
	double	dBaseLineE;			//结束基线
	double	dPeakCenterTime;	//最高峰时间
	double	dPeakH;				//峰高
	double	dPeakArea;			//峰面积
};

struct CHROM_LIST				//分析历史谱图
{
	CString strFileName;		//谱图文件名
	int		nCH;				//组份A,组份B
};

class CGlobal
{
public:
	CGlobal(void);
	~CGlobal(void);

public:
	int				m_nMachineStatus;			//仪器状态 0-开机，1--正在预加热等，2--正常工作（只有正常工作时才进行语音输出） 
	long			MAXPOINTS;
	BOOL			m_bConnChrom;				//是否已连接色谱控制板
	long			m_nReceiveAD;				//接收到A通道网络信号
	long			m_nReceiveBD;				//接收到B通道网络信号
	BOOL			m_bConnDLS;					//是否已连接DML-LS
	BOOL			m_bRun;						//是否正在分析
	BOOL			m_bRunA;					//是否正在分析--CHA
	BOOL			m_bRunB;					//是否正在分析--CHB
	bool			m_bTwoChCalibreate;			//是否在双通道的校准模式下

	bool			bExitThread;
	bool			bReceiveSwitchReturnA;		//收到切阀后的反馈
	bool			bReceiveSwitchReturnB;		//收到切阀后的反馈

	CString			m_strNewMsg1;				//新的语音消息（FID点火状态，通信状态）
	CString			m_strNewMsg2;				//新的语音消息 （温控及EPC控制）

	//2022-10-26增加
	bool			m_bRunBaseLine;				//是否在跑基线
	double			m_dBaseLineAreaA[6];		//六个基线最大峰面积
	double			m_dBaseLineAreaB[6];
	void			CalculateBaseLine();		//查找基线最大峰面积

	bool			m_bAarmSwitchOff;			//报警总开关
	bool			m_bUseBaseLineAdj;			//使用基线校正

	int				m_FireNumA;					//组份A点火次数
	int				m_FireNumB;					//组份B点火次数
	int				m_FireNumC;					//组份C点火次数
	int				fire_num;					//自动点火次数				
	bool			fire_status;				//是否开启自动点火线程
	
//界面相关
public:
	CFont			m_pFont;				//显示字体1
	CFont			m_pSmallFont;			//显示字体2
	HBRUSH			m_brBack1;
	HBRUSH			m_brBack2;

public:
	CString			m_strSystemInfo;	//系统信息
	CString			m_strDebugInfo;		//调试信息
	CString			m_strWellName;		//井名
	int				m_nWorkMode;		//工作模式，0--双通道；1--通道A;2--通道B;3--差分；
	int				m_nUnit;			//输出单位，0-%，1-ppm
	int				m_nCycleType;		//工作周期，0--30秒，1--90秒；
	int				m_nMethodFileVersion;	//文件版本号

	Calibrate_Info	gcCi;				//标定信息
	Machine			gcMachine;			//仪器信息
	MachineStatus	gcStatus;			//仪器状态
	CArray<CHROM_LIST, CHROM_LIST& >  m_lstChromFiles;		//谱图文件

	float			m_dLagDepth;		//迟到井深
	float			m_dLagTime;			//迟到时间 //Add By WNT @2024-01-19
	float			m_dTGResult;		//实时全烃
	float			m_dCO2Result;		//实时CO2
	ChromWITS		ChromWits;
	Chrom_File		curChromA;			//最新的谱图A通道--未积分
	Chrom_File		curChromB;			//最新的谱图B通道--未积分
	int				nReCaculate;		//是否有新的积分，有则进行界面更改 0-不需要更新，1--更新lastChromA，2--更新lastChromB，3--更新lastChromA，曲线颜色为B
	int				nFinishCaculate[2];	//两个通道是否完成积分计算，0--未完成，1--完成； 只用于两通道校准
	Chrom_File		lastChromA;			//最新的积分谱图--已积分
	Chrom_File		lastChromB;			//最新的积分谱图--已积分  只有差分模式时才启用lastChromB
										//其它工作模式都传值给lastChromA
public: //切换数字键盘与完全键盘
	CString m_strExe1Path;
    CString m_strExe2Path;
    bool m_bIsExe1Visible;
    PROCESS_INFORMATION m_ProcInfo1; // 进程信息
    PROCESS_INFORMATION m_ProcInfo2; // 进程信息


	bool StartExe(LPCTSTR exePath, PROCESS_INFORMATION& procInfo); // 启动exe文件的函数

	void ButtonToggle();
	void ButtonToggleNum();
	void ButtonToggleH();
public:
	void	LoadSoftwareSetting();
	void	SaveSoftwareSetting();

	//方法文件
	void	LoadCalMethod(CString strFileName);
	void	SaveCalMethod(CString strFileName);

private:
	double GetCurveR(int nCH,int index, double dArea);

	//自动判峰
public:
	double		m_dMinXLA;			//mv/s
	double		m_dMinXLB;			//mv/s


private:
	//最小峰高和最小峰面积
	double		m_dMinPeakHeight;	//mv
	double		m_dMinPeakAreaA;		//mv*s
	double		m_dMinPeakAreaB;		//mv*s
	double		m_dMinPeakWidth;		//最小峰宽
	double		m_dXLChgPar;			//斜率变换系数

	//计算谱图的斜率
	CArray<PEAK_INOF, PEAK_INOF&> arrResult;			//放在这里是为了调试
	double	CaculateCurveXL(CArray<CurveData, CurveData&>* arrPoint);
	int		CaculateChromCurve(CArray<CurveData, CurveData&>& arrData, CArray<PEAK_INOF, PEAK_INOF&>& arrResult, bool bIsBChannel);

public:
	void	SaveChromFile(int nCh,int nChromFile,bool bAddOrg);
	Chrom_File ReadChmDate(CString strFile);
	Chrom_File	CaculateChrm(Chrom_File cf,bool bIsBChannel);

	double  CaculateResult(int nCH,int index, double dArea);
	double	CaculateFlow(int nIndex, double dFlowV);
	void    CaculateTG();
	void    CaculateCO2();
	void	CaculateK(int nNums, float* dC, float* dA, double& dK, double& dB, double& dR);

	BOOL    FiredEnabled(int nType);		//允许点火的条件判断
	BOOL    EPCStatusAlert();	//各种压力值偏离 5% 的提示判断
	
private:
	double   GetMistake(double Value_Set, double Value);
	double   GetMistakeTemp(double Value_Set, double Value);

private:
	//色谱峰的较准
	//Chrom_File	RegulateChrm(Chrom_File cf);
	//float   CD[6000];				//通道数据,单位mV
	//float   CT[6000];				//通道A时间,单位s
	//int		m_nTotalNums;			//最大数据序号INDEX
	//Chrom_File	RegulatePeakWidth(Chrom_File cf);	//峰宽较准
	//Chrom_File	HorMovePeak(Chrom_File cf);			//峰平移

	//数据库相关操作
public:
	void	OpenCurWellDB();
	_ConnectionPtr OpenDB(CString strMdbFileName);
	bool	ExcuteWellSQL(CString strSQL);
	bool	ZipAccessDB(CString strMdbFileName);			//压缩数据库
	bool	GetDbTimeInfo(long& lStartTime, long& lEndTime);	//获取数据库时间范围

public:
	//数字键盘
	//CString StartNumberKeyBoard(int nL, int nB, CString strTemp);
	void	StartNumberKeyBoard();
	void	StartKeyBoard();
	void	CloseKeyBoard();
	void	CloseNumberKeyBoard();
};


extern CGlobal gl;

